﻿Imports LuceneSearch.Monitoring.Interfaces
Imports DotNetNuke.Services.Log.EventLog

Namespace LuceneSearch.Monitoring.Monitors

    Public Class IndexationMonitor
        Implements ILogInfoProvider


        Public ReadOnly Property Items As Integer
            Get
                Return NativeSearchItemsHandler.Count _
                    + ExtendedSearchItemsHandler.Count _
                    + ProgressiveStandaloneSearchItemsHandler.Count _
                    + StandaloneSearchItemsHandler.Count _
                    + ReflexiveSearchItemsHandler.Count
            End Get
        End Property

        Private _NativeSearchItemsHandler As New ModuleToSearchItemsHandler
        Public ReadOnly Property NativeSearchItemsHandler As ModuleToSearchItemsHandler
            Get
                Return _NativeSearchItemsHandler
            End Get
        End Property

        Private _ExtendedSearchItemsHandler As New ModuleToSearchItemsHandler
        Public ReadOnly Property ExtendedSearchItemsHandler As ModuleToSearchItemsHandler
            Get
                Return _ExtendedSearchItemsHandler
            End Get
        End Property

        Private _ProgressiveStandaloneSearchItemsHandler As New ProvidersToSearchItemsHandler
        Public ReadOnly Property ProgressiveStandaloneSearchItemsHandler As ProvidersToSearchItemsHandler
            Get
                Return _ProgressiveStandaloneSearchItemsHandler
            End Get
        End Property

        Private _StandaloneSearchItemsHandler As New ProvidersToSearchItemsHandler
        Public ReadOnly Property StandaloneSearchItemsHandler As ProvidersToSearchItemsHandler
            Get
                Return _StandaloneSearchItemsHandler
            End Get
        End Property

        Private _ReflexiveSearchItemsHandler As New ProvidersToSearchItemsHandler
        Public ReadOnly Property ReflexiveSearchItemsHandler As ProvidersToSearchItemsHandler
            Get
                Return _ReflexiveSearchItemsHandler
            End Get
        End Property

        Public Class ModuleToSearchItemsHandler
            Public Class ModuleCountInfo
                Public Property ModuleId As Integer
                Public Property ItemCount As Integer
            End Class

            Public Property ModuleToSearchItem As New Dictionary(Of String, Integer)
            Public Property ModuleToManySearchItems As New Dictionary(Of String, List(Of ModuleCountInfo))

            Public Sub AddItems(ModuleName As String, ModuleId As Integer, ItemCount As Integer)
                If ItemCount > 0 Then
                    If ItemCount = 1 Then
                        If Not ModuleToSearchItem.ContainsKey(ModuleName) Then
                            ModuleToSearchItem.Add(ModuleName, 0)
                        End If
                        ModuleToSearchItem(ModuleName) += ItemCount
                    Else
                        If Not ModuleToManySearchItems.ContainsKey(ModuleName) Then
                            ModuleToManySearchItems.Add(ModuleName, New List(Of ModuleCountInfo))
                        End If
                        ModuleToManySearchItems(ModuleName).Add(New ModuleCountInfo() With {.ModuleId = ModuleId, .ItemCount = ItemCount})
                    End If
                End If
            End Sub

            Public ReadOnly Property Count As Integer
                Get
                    Return ModuleToSearchItem.Values.Sum() + ModuleToManySearchItems.Select(Function(e) e.Value.Sum(Function(nmtsi) nmtsi.ItemCount)).Sum()
                End Get
            End Property

            Public Function RetrieveAsLogInfo(content As String) As LogInfo
                Dim CurrentLogInfo As New LogInfo()
                CurrentLogInfo.AddProperty("LuceneSearch indexation", content)
                CurrentLogInfo.AddProperty("Total items", Count.ToString())
                For Each element In ModuleToSearchItem
                    CurrentLogInfo.AddProperty(String.Format("Module {0} returning a single item", element.Key), element.Value.ToString())
                Next
                For Each element In ModuleToManySearchItems
                    CurrentLogInfo.AddProperty("---", "---")
                    CurrentLogInfo.AddProperty(String.Format("Module {0} returning multiple items", element.Key), String.Empty)
                    For Each subelement In element.Value
                        CurrentLogInfo.AddProperty(String.Format("{0} #{1}", element.Key, subelement.ModuleId), subelement.ItemCount.ToString())
                    Next
                    CurrentLogInfo.AddProperty("---", "---")
                Next

                Return CurrentLogInfo
            End Function
        End Class

        Public Class ProvidersToSearchItemsHandler
            Public Class ProviderCountInfo
                Public Property ProviderName As String
                Public Property ItemsCount As Integer
            End Class

            Private _ProviderItems As New List(Of ProviderCountInfo)

            Public Sub AddItems(Provider As String, ItemCount As Integer)
                _ProviderItems.Add(New ProviderCountInfo() With {.ProviderName = Provider, .ItemsCount = ItemCount})
            End Sub

            Public ReadOnly Property Count As Integer
                Get
                    Return _ProviderItems.Select(Function(d) d.ItemsCount).Sum()
                End Get
            End Property

            Public Function RetrieveAsLogInfo(content As String) As LogInfo
                Dim CurrentLogInfo As New LogInfo()
                CurrentLogInfo.AddProperty("LuceneSearch indexation", content)
                CurrentLogInfo.AddProperty("Total items", Count.ToString())
                For Each element In _ProviderItems
                    CurrentLogInfo.AddProperty(String.Format("Provider {0}", element.ProviderName), element.ItemsCount.ToString())
                Next

                Return CurrentLogInfo
            End Function
        End Class

        Public Function GetLogInfos() As System.Collections.Generic.IEnumerable(Of LogInfo) Implements Interfaces.ILogInfoProvider.GetLogInfos
            Dim IndexationLogInformations As New List(Of LogInfo)

            IndexationLogInformations.Add(NativeSearchItemsHandler.RetrieveAsLogInfo("Native search items stats"))
            IndexationLogInformations.Add(ExtendedSearchItemsHandler.RetrieveAsLogInfo("Extended search items stats"))
            IndexationLogInformations.Add(ProgressiveStandaloneSearchItemsHandler.RetrieveAsLogInfo("Progressive search items stats"))
            IndexationLogInformations.Add(StandaloneSearchItemsHandler.RetrieveAsLogInfo("Standalone search items stats"))
            IndexationLogInformations.Add(ReflexiveSearchItemsHandler.RetrieveAsLogInfo("Reflexive search items stats"))

            Return IndexationLogInformations.Skip(0) ' returns a true enumerable
        End Function
    End Class

End Namespace
